package com.itlong.cloud.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.app.AppAuthPersonGetRoomInfoDTO;
import com.itlong.cloud.POJO.DTO.app.AppGetAuthPersonPageDTO;
import com.itlong.cloud.POJO.DTO.app.AppMineAuthPersonExtendDTO;
import com.itlong.cloud.POJO.DTO.operate.ProjectSmartCommunityStatusChangeDTO;
import com.itlong.cloud.POJO.DTO.property.PropertySubscriberHanlerDTO;
import com.itlong.cloud.POJO.DTO.smartcard.SmartCardSyncDataPullDTO;
import com.itlong.cloud.POJO.DTO.smartcard.SmartCardSyncDataPullUserBasisInfoDTO;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.app.*;
import com.itlong.cloud.POJO.VO.property.PropertyQrcodeValidVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.app.dao.IAppMineDao;
import com.itlong.cloud.app.dao.IAppRegisterDao;
import com.itlong.cloud.app.dao.IAppUserLykzAccountDao;
import com.itlong.cloud.app.service.IAppLykzCloudIntercomAccountService;
import com.itlong.cloud.app.service.IAppMineService;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.operate.dao.IOperateUserFeedbackDao;
import com.itlong.cloud.operate.dao.IOperateUserManageDao;
import com.itlong.cloud.property.dao.IPropertyAppAuthRelationsDao;
import com.itlong.cloud.property.dao.IPropertyAppUserProjectDao;
import com.itlong.cloud.property.dao.IPropertyAppUserRoomDao;
import com.itlong.cloud.property.service.IPropertyHouseHoldInfoService;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.smartcard.dao.ISmartCardUserInfoDao;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.string.StringUtil;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import sun.misc.BASE64Decoder;

import java.io.ByteArrayInputStream;
import java.net.URLDecoder;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * <desc>
 *     APP的我的板块服务层实现类
 * </desc>
 *
 * @createDate 2017/10/10
 */
@Service
@RefreshScope
public class AppMineServiceImpl implements IAppMineService{

    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;


    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;

    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;

    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;

    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    @Value("${" + PlatformConstants.APP_USER_TOKEN_KEY + "}")
    String userTokenKey;

    @Autowired
    IAppRegisterDao iAppRegisterDao;

    @Autowired
    IAppMineDao iAppMineDao;

    @Autowired
    IOperateUserFeedbackDao iOperateUserFeedbackDao;

    @Autowired
    IPropertyAppUserProjectDao iPropertyAppUserProjectDao;

    @Autowired
    IPropertyAppUserRoomDao iPropertyAppUserRoomDao;

    @Autowired
    IPropertyAppAuthRelationsDao iPropertyAppAuthRelationsDao;

    @Autowired
    IPropertyHouseHoldInfoService iPropertyHouseHoldInfoService;

    //消息队列
    @Autowired
    private MessageSender messageSender;

    @Autowired
    private RedisService<AppUserCacheVO> redisService;

    @Autowired
    private ISmartCardUserInfoDao iSmartCardUserInfoDao;

    @Autowired
    IOperateUserManageDao iOperateUserManageDao;



    @Autowired
    IAppLykzCloudIntercomAccountService iAppLykzCloudIntercomAccountService;

    @Autowired
    private IAppUserLykzAccountDao iAppUserLykzAccountDao;

    private static final Logger LOG = LoggerFactory.getLogger(AppMineServiceImpl.class);

    public static final String REPLY_CONTENT = "我们已收到您的反馈，部分功能将在后续版本中进行优化，感谢您的支持与反馈！";
    public static final String COMMIT_FEEDBACK = "提交意见反馈";


    /**
     * <desc>
     *      注销账号
     * </desc>
     *
     * @param userId
     * @author Jiaqi.X
     * @createDate 2020/06/01
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void logOff(String userId) throws Exception {
        AppUserInfoPO appUserInfoPO = iAppMineDao.getUserInfoByUserId(userId);
        AppLogoffUserHistoryPO logoff = new AppLogoffUserHistoryPO();
        logoff.setUserId(appUserInfoPO.getUserId());
        logoff.setPhone(appUserInfoPO.getPhoneNum());
        logoff.setLogoffTime(new Date());
        logoff.setRealName(appUserInfoPO.getRealName());
        logoff.setCreateTime(logoff.getLogoffTime());
        logoff.setUpdateTime(logoff.getLogoffTime());
        logoff.setLogoffUserId(LogicIdUtil.bussinessId());
        logoff.setStatus(DataStatusEnum.NORMAL.getType());
        //删除小程序绑定数据
        iAppMineDao.deleteMiniUserName(userId);
        //处理项目数据
        iAppMineDao.setLogOffUserProjectByUserId(userId);
        //处理房间数据
        iAppMineDao.setLogOffUserRoomByUserId(userId);
        //处理设备权限数据
        iAppMineDao.setLogOffUserElevatorByUserId(userId);
        iAppMineDao.setLogOffUserEntranceByUserId(userId);
        iAppMineDao.setLogOffUserCloudIntercomByUserId(userId);
        iAppMineDao.logOff(userId);
        iAppMineDao.save(SqlUtil.durableData(logoff,PlatformConstants.TABLE_SAVE));
    }

    /**
     * <desc>
     *     APP端_我的,退出登录
     * </desc>
     * @param userId
     * @return
     * @createDate 2017/10/10
     * @author cuiduanwu
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public boolean logOut(String userId) throws Exception{
        AppUserCacheVO appUserCacheVO = redisService.getObject(RedisConstant.APP_LOGIN+userId,AppUserCacheVO.class);
        boolean redisflag = redisService.set(RedisConstant.APP_LOGIN + userId,RedisConstant.LOGIN_OUT_APP_USER_TOKEN_TIME,appUserCacheVO);
        if (!redisflag){
            LOG.info("【APP端_我的版块】登出清理缓存失败");
        }


        AppUserInfoPO appUserInfoPO = new AppUserInfoPO(userId);
        appUserInfoPO.setIsOnline(0);
        boolean flag = iAppRegisterDao.updateByPoNotNull(appUserInfoPO)>0?true:false;
        if (flag){
            if (appUserCacheVO != null){
                List<AppUserOwnProjectVO> userOwnProjectList = appUserCacheVO.getProjects();
                if (userOwnProjectList != null&&userOwnProjectList.size()>0){
                    for (AppUserOwnProjectVO appUserOwnProjectVO:userOwnProjectList){
                        JSONObject js = new JSONObject();
                        js.put("projectId",appUserOwnProjectVO.getProjectId());
                        js.put("userId",appUserCacheVO.getUserId());
                        DeviceBusinessChangeLogPO deviceBusinessChangeLogPO = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_USER_PROJECT,js,appUserOwnProjectVO.getProjectId());
                        List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
                        changeLogPOS.add(deviceBusinessChangeLogPO);
                        if (changeLogPOS != null && !changeLogPOS.isEmpty()) {
                            JSONObject datajs = new JSONObject();
                            datajs.put("data",changeLogPOS);
                            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                                    JSON.toJSONString(datajs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
                        }
                    }
                }
            }
        }
        return flag;
    }

    /**
     * <desc>
     *     APP端_我的,更新头像
     * </desc>
     * @param userId
     * @param imageStr
     * @param imageType
     * @return
     * @createDate 2017/10/10
     * @author cuiduanwu
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public String updatePhoto(String userId,String imageStr,String imageType) throws  Exception{
        String imageUrl = null;
        try {
            imageStr = URLDecoder.decode(imageStr, "UTF-8");
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] bytes = decoder.decodeBuffer(imageStr);
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                    FILE_FTP_HOST,
                    FILE_FTP_USERNAME,
                    FILE_FTP_PASSWORD,
                    FILE_FTP_PORT,
                    byteArrayInputStream,
                    imageType,
                    FILE_ACCESS_URL,
                    FileCatalogEnum.APPLOGO_FILE.getType()
            );
            Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
            if ("true".equals(resultMap.get("returnCode").toString())){
                imageUrl = resultMap.get("accessPath").toString();
                AppUserInfoPO appUserInfoPO = new AppUserInfoPO(userId,null,null,imageUrl,null);
                int i = iAppRegisterDao.updateByPoNotNull(appUserInfoPO);
                if (i>0){
                    AppUserCacheVO appUserCacheVO = redisService.getObject(RedisConstant.APP_LOGIN+userId,AppUserCacheVO.class);
                    if (appUserCacheVO != null){
                        appUserCacheVO.setPhotoUrl(imageUrl);
                        redisService.set(RedisConstant.APP_LOGIN+userId,RedisConstant.APP_USER_TOKEN_TIME,appUserCacheVO);
                    }
                    return  imageUrl;
                }else {
                    throw new DataAccessException("【APP端_我的版块】更新用户头像记录失败");
                }
            }else {
                throw new DataAccessException("【APP端_我的版块】更新用户头像上传失败");
            }
        }catch (Exception e){
            throw new DataAccessException("【APP端_我的版块】更新用户头像失败",e);
        }
    }


    /**
     * <desc>
     *     APP端_我的,更新昵称
     * </desc>
     * @param userId
     * @param nickName
     * @return
     * @createDate 2017/10/10
     * @author cuiduanwu
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public boolean updateNickName(String userId,String nickName){
        AppUserInfoPO appUserInfoPO = new AppUserInfoPO(userId,nickName,null,null,null);
        boolean flag = iAppRegisterDao.updateByPoNotNull(appUserInfoPO)>0?true:false;
        AppUserCacheVO appUserCacheVO = redisService.getObject(RedisConstant.APP_LOGIN+userId,AppUserCacheVO.class);
        if (appUserCacheVO != null&&flag){
            appUserCacheVO.setNickName(nickName);
            redisService.set(RedisConstant.APP_LOGIN+userId,RedisConstant.APP_USER_TOKEN_TIME,appUserCacheVO);
        }
        return  flag;
    }


    /**
     * <desc>
     *     APP端_我的,更新性别
     * </desc>
     * @param userId
     * @param sex
     * @return
     * @createDate 2017/10/10
     * @author cuiduanwu
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public boolean updateSex(String userId,String sex){
        AppUserInfoPO appUserInfoPO = new AppUserInfoPO(userId,null,null,null,Integer.parseInt(sex));
        boolean flag = iAppRegisterDao.updateByPoNotNull(appUserInfoPO)>0?true:false;
        AppUserCacheVO appUserCacheVO = redisService.getObject(RedisConstant.APP_LOGIN+userId,AppUserCacheVO.class);
        if (appUserCacheVO != null&&flag){
            appUserCacheVO.setSex(sex);
            redisService.set(RedisConstant.APP_LOGIN+userId,RedisConstant.APP_USER_TOKEN_TIME,appUserCacheVO);
        }
        return  flag;
    }


    /**
     * <desc>
     *     APP端_我的版块,新增意见反馈
     * </desc>
     * @param userId
     * @param projectId
     * @param feedBackInfo
     * @return
     * @author cuiduanwu
     * @createDate 2017/10/10
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public boolean addFeedBackInfo(String userId, String projectId, String feedBackInfo,
                                   String problemType, String appVersion, String androidVersion, String phoneModel,
                                   String contactInformation, String imageUrlStr, String netType, String systemName) throws Exception {
        FeedbackInfoPO feedbackInfoPO = new FeedbackInfoPO(userId, projectId, feedBackInfo, 0, new Date());
        feedbackInfoPO.setFeedbackId(LogicIdUtil.bussinessId());
        feedbackInfoPO.setProblemType(StringHandlerUtil.strToIntDef(problemType, 1));
        feedbackInfoPO.setAppVersion(appVersion);
        feedbackInfoPO.setAndroidVersion(androidVersion);
        feedbackInfoPO.setPhoneModel(phoneModel);
        feedbackInfoPO.setContactInformation(contactInformation);
        feedbackInfoPO.setImageUrl(imageUrlStr);
        feedbackInfoPO.setNetType(netType);
        feedbackInfoPO.setOperateSystem(systemName);
        Integer result = iOperateUserFeedbackDao.save(SqlUtil.durableData(feedbackInfoPO, PlatformConstants.TABLE_SAVE));
        return result > 0;
    }

    /**
     * <desc>
     *     APP端_我的,更新密码
     * </desc>
     * @param userId
     * @param oldPswd 加密后的旧密码
     * @param currentPswd 加密后的新密码
     * @return
     * @author cuiduanwu
     * @createDate 2017/10/11
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public boolean updatePswd(String userId,String oldPswd,String currentPswd){
        boolean flag = false;
        AppUserInfoPO appUserInfoPO = new AppUserInfoPO(userId);
        AppUserInfoPO appUserInfo = iAppRegisterDao.getOne(appUserInfoPO);
        if (appUserInfo != null&&appUserInfo.getPassword().equals(oldPswd)){
            appUserInfoPO.setPassword(currentPswd);
            int result =iAppRegisterDao.updateByPoNotNull(appUserInfoPO);
            if (result>0){
                flag = true;
            }
        }
        return  flag;
    }

    /**
     * <desc>
     *      APP端_我的_获取授权人列表信息。
     * <desc/>
     *
     * @param pageDTO 分页查询请求参数
     * @return
     * @author shengen.T
     * @createDate 2017/11/10
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public Page<AppMineGetAuthPersonPageVO> getAuthPersonPage(AppGetAuthPersonPageDTO pageDTO) throws Exception{
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(pageDTO);
        //分页类默认pageSize为20
        Page<AppMineGetAuthPersonPageVO> page = new Page<>();
        String pageSize = "-1".equals(pageDTO.getPageSize())?"999":pageDTO.getPageSize();
        page.getPage().setPageSize(pageSize);
        page.getPage().setCurrentPage(pageDTO.getPageNo());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        List<AppMineGetAuthPersonPageVO> pageVOS = iAppMineDao.getAuthPersonPage(params);
        AppAuthPersonGetRoomInfoDTO appAuthPersonGetRoomInfoDTO = new AppAuthPersonGetRoomInfoDTO();
        appAuthPersonGetRoomInfoDTO.setProjectId(pageDTO.getProjectId());
        appAuthPersonGetRoomInfoDTO.setLoginUserId(pageDTO.getLoginUserId());
        if((pageVOS!=null)&&(pageVOS.size()>0)){
            for(AppMineGetAuthPersonPageVO itemVO:pageVOS){
                //判断是否是注册用户
                if(StringUtils.isBlank(itemVO.getPassword())){
                    itemVO.setUserName("");
                }
                appAuthPersonGetRoomInfoDTO.setAuthPhoneNo(itemVO.getPhoneNo());
                List<AppMineGetAddressInfoVO> authPersonRoomInfo = this.getAuthPersonRoomInfo(appAuthPersonGetRoomInfoDTO);
                itemVO.setAddressInfo(authPersonRoomInfo);
            }
        }
        //填充返回数据集
        page.setRows(pageVOS,iAppMineDao.getPageCount(params));
        return page;
    }

    /**
     * <desc>
     *      获取被授权人的房间信息。
     * <desc/>
     *
     * @param  pageDTO
     * @return
     * @author shengen.T
     * @createDate 2018-01-23
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public List<AppMineGetAddressInfoVO> getAuthPersonRoomInfo(AppAuthPersonGetRoomInfoDTO pageDTO) throws Exception{
        AppUserInfoPO userInfoPO= iAppMineDao.getUserInfoByPhoneNo(pageDTO.getAuthPhoneNo());
        if(userInfoPO==null){
            return null;
        }
        List<AppMineGetAddressInfoVO> addressInfoVOS = iAppMineDao.getAddressInfo(pageDTO.getLoginUserId(),userInfoPO.getUserId(),pageDTO.getProjectId());
        return addressInfoVOS;
    }


     /**
      * <desc>
      *      添加授权人信息_需要事物回滚。
      * <desc/>
      *
      * @param  * @param null
      * @return
      * @author shengen.T
      * @createDate 2018-02-25
      */
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Map<String, Object> addAuthPersonTransactional(AppMineAuthPersonExtendDTO saveDTO,String[] roomIdArr,boolean success,ProjectPO projectPO) throws Exception{
        if(saveDTO.getAppUserInfoPO()!=null){
            iAppRegisterDao.save(SqlUtil.durableData(saveDTO.getAppUserInfoPO(), PlatformConstants.TABLE_SAVE));
        }
       // List<AppMineRoomInfoVO> roomInfoVOList = new ArrayList<>();
        Map<String, Object> resultMap = new HashMap<>(); //返回结果
        //人跟项目关系信息
        AppUserProjectPO upPO = new AppUserProjectPO(saveDTO.getUserId(),saveDTO.getProjectId(),
                "0","000000","1",1,1,new Date());
        Integer upResultCount=0;

        //判断人跟项目表现表是否有记录
        Integer upCount = iAppMineDao.checkUsrProject(saveDTO.getUserId(),saveDTO.getProjectId());
        if(upCount>0){
            upResultCount=iAppMineDao.setUserProjectStatus(saveDTO.getUserId(),saveDTO.getProjectId(),1);
        }else {
            upResultCount = iPropertyAppUserProjectDao.save(SqlUtil.durableData(upPO, PlatformConstants.TABLE_SAVE));
            //sip账号统一处理
            ProjectSmartCommunityStatusChangeDTO sipInfo = new ProjectSmartCommunityStatusChangeDTO();
            sipInfo.setIsSmartCommunity(saveDTO.getIsSmartCommunity());
            sipInfo.setProjectId(saveDTO.getProjectId());
            sipInfo.setUserId(saveDTO.getUserId());
            iPropertyHouseHoldInfoService.updateUserProjectSip(sipInfo);

        }
        if(upResultCount>0){
            //保存住户入住历史
            List<AppUserStayInHistoryPO> appUserStayInHistoryPOS = new ArrayList<>();
            //某业主的所有房间开门密码统一，获取开门密码一次
            String openPwd = iAppMineDao.getOpenPassword(saveDTO.getLoginUserId(),saveDTO.getProjectId(),roomIdArr[0]);
            //判断人跟房间关系表是否有记录,并且添加新的房间关信息
            Integer aurCount =0;
            //维护人跟房间的关系
            List<AppMineRoomInfoVO> roomIdList = iAppMineDao.getAuthRelationsRoomInfos(saveDTO.getProjectId(),saveDTO.getUserId(),saveDTO.getLoginUserId());
            List<String> newRoomIdList = Arrays.asList(roomIdArr);//新的绑定房间ID信息
            if(roomIdList!=null&&roomIdList.size()>0){
                //房屋迁出参数设置
                Map<String,Object> moveOutParams = new HashMap<>();
                moveOutParams.put("userId",saveDTO.getUserId());
                moveOutParams.put("projectId",saveDTO.getProjectId());
                moveOutParams.put("status", UserRoomStatusTypeEnum.HOUSE_MOVE_OUT.getType());
                moveOutParams.put("authUserId", "-1");
                for (AppMineRoomInfoVO roomInfo:roomIdList){
                    if(!newRoomIdList.contains(roomInfo.getRoomId())){
                        moveOutParams.put("roomId",roomInfo.getRoomId());
                        iAppMineDao.updateUserRoomInfo(moveOutParams);
                        //保存住户入住历史
                        AppUserStayInHistoryPO appUserStayInHistoryPO = new AppUserStayInHistoryPO(saveDTO.getUserId(),
                                saveDTO.getProjectId(), roomInfo.getBuildId(), roomInfo.getUnitId(), roomInfo.getRoomId(),
                                roomInfo.getRoomNum(),UserRoomStatusTypeEnum.HOUSE_MOVE_OUT.getType());
                        appUserStayInHistoryPOS.add(appUserStayInHistoryPO);
                    }
                }
            }
            //房屋迁入信息设置（固定值）
            Map<String,Object> moveInParams = new HashMap<>();
            moveInParams.put("projectId",saveDTO.getProjectId());
            moveInParams.put("userId",saveDTO.getUserId());
            moveInParams.put("source","1");
            if(StringUtils.isNotBlank(openPwd)){
                moveInParams.put("openPwd",openPwd);
            }
            //获取项目配置
            Integer userRoomStatus;
            if (0 == projectPO.getRecheckStatus()){
                //物业二次审批开关
                userRoomStatus = UserRoomStatusTypeEnum.HOUSE_MOVE_IN.getType();

            }else {
                userRoomStatus = UserRoomStatusTypeEnum.HOUSE_WAIT_CHECK.getType();
            }
            moveInParams.put("status", userRoomStatus);

            List<AppMineRoomInfoVO> roomInfoVOList=iAppMineDao.getRoomInfoList(roomIdArr);
            for (AppMineRoomInfoVO roomInfoVO:roomInfoVOList){
                boolean isMoveIn= false;
                //存在房间记录
                AppUserRoomPartVO roomPortInfo = iAppMineDao.getUserRoomPortInfo(saveDTO.getUserId(),saveDTO.getProjectId(),roomInfoVO.getRoomId());
                if((roomPortInfo!=null)&&(UserRoomStatusTypeEnum.HOUSE_MOVE_IN.getType().toString().equals(roomPortInfo.getUserRoomStatus())
                        || UserRoomStatusTypeEnum.HOUSE_WAIT_CHECK.getType().toString().equals(roomPortInfo.getUserRoomStatus()))
                        &&("1".equals(roomPortInfo.getStatus()))&&(!"1".equals(roomPortInfo.getSource()))){
                    //回滚当前事务
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    resultMap.put("returnCode", false);
                    if ((UserRoomStatusTypeEnum.HOUSE_MOVE_IN.getType().toString().equals(roomPortInfo.getUserRoomStatus()))){
                        resultMap.put("hintInfo",String.format("%s%s%s","住户已存在{",roomPortInfo.getRoomNum(),"}房间，请重新选择"));
                    }
                    if (UserRoomStatusTypeEnum.HOUSE_WAIT_CHECK.getType().toString().equals(roomPortInfo.getUserRoomStatus())){
                        resultMap.put("hintInfo",String.format("%s%s%s","住户在{",roomPortInfo.getRoomNum(),"}房间正在被审核，请勿重复提交"));
                    }
                    return  resultMap;
                }
                if((roomPortInfo!=null)&&(StringUtils.isNotBlank(roomPortInfo.getUserId()))){
                    moveInParams.put("roomId",roomInfoVO.getRoomId());
                    //授权人的userId,当用户房间状态为待审核时，保存于用户设备权限表中授权人id字段
                    moveInParams.put("authUserId", saveDTO.getLoginUserId());
                    moveInParams.put("houserType",NumberHandlerUtil.isInRange(saveDTO.getHouserType(),2,3) ? saveDTO.getHouserType().toString() : "2");
                    //LOG.info("【标记前迁入状态】：" + roomPortInfo.getUserRoomStatus());
                    if ("2".equals(roomPortInfo.getUserRoomStatus())) {
                        moveInParams.put("theMark","theMark");
                        moveInParams.put("status", roomPortInfo.getUserRoomStatus());
                    } else {
                        moveInParams.put("status", userRoomStatus);
                        moveInParams.remove("theMark");
                    }
                    iAppMineDao.updateUserRoomInfo(moveInParams);
                    aurCount++;
                }else {
                    Date nowTime = new Date();
                    AppUserRoomPO urPO = new AppUserRoomPO(saveDTO.getUserId(),
                            saveDTO.getProjectId(),roomInfoVO.getBuildId(),
                            roomInfoVO.getUnitId(),roomInfoVO.getRoomNum(),roomInfoVO.getRoomId(),
                            userRoomStatus,NumberHandlerUtil.isInRange(saveDTO.getHouserType(),2,3) ? saveDTO.getHouserType() : 2,1,1,nowTime,openPwd);
                    urPO.setUpdateTime(nowTime);
                    urPO.setAuthUserId(saveDTO.getLoginUserId());
                    iPropertyAppUserRoomDao.save(SqlUtil.durableData(urPO, PlatformConstants.TABLE_SAVE));
                    aurCount++;
                    if (userRoomStatus == UserRoomStatusTypeEnum.HOUSE_MOVE_IN.getType()){
                        isMoveIn = true;
                    }
                }
                //保存住户入住历史
                if(isMoveIn){
                    AppUserStayInHistoryPO appUserStayInHistoryPO = new AppUserStayInHistoryPO(saveDTO.getUserId(),
                            saveDTO.getProjectId(), roomInfoVO.getBuildId(), roomInfoVO.getUnitId(), roomInfoVO.getRoomId(),
                            roomInfoVO.getRoomNum(),UserRoomStatusTypeEnum.HOUSE_MOVE_IN.getType());
                    appUserStayInHistoryPOS.add(appUserStayInHistoryPO);
                }
            }
            /*
            for (int i=0;i<roomIdArr.length;i++){
                //根据房间ID获取楼栋和单元Id等
                AppMineRoomInfoVO roomInfoVO = iAppMineDao.getRoomInfo(roomIdArr[i]);
                roomInfoVO.setRoomId(roomIdArr[i]);
                roomInfoVOList.add(roomInfoVO);
                boolean isMoveIn= false;
//                //存在房间记录
//                AppUserRoomPartVO roomPortInfo = iAppMineDao.getUserRoomPortInfo(saveDTO.getUserId(),saveDTO.getProjectId(),roomIdArr[i]);
//                if((roomPortInfo!=null)&&("2".equals(roomPortInfo.getUserRoomStatus()))
//                        &&("1".equals(roomPortInfo.getStatus()))&&(!"1".equals(roomPortInfo.getSource()))){
//                    //回滚当前事务
//                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                    resultMap.put("returnCode", false);
//                    resultMap.put("hintInfo",String.format("%s%s%s","住户已存在{",roomPortInfo.getRoomNum(),"}房间，请重新选择"));
//                    return  resultMap;
//                }
//                if((roomPortInfo!=null)&&(StringUtils.isNotBlank(roomPortInfo.getUserId()))){
//                    moveInParams.put("roomId",roomIdArr[i]);
//                    iAppMineDao.updateUserRoomInfo(moveInParams);
//                    aurCount++;
//                }else {
//                    Date nowTime = new Date();
//                    AppUserRoomPO urPO = new AppUserRoomPO(saveDTO.getUserId(),
//                            saveDTO.getProjectId(),roomInfoVO.getBuildId(),
//                            roomInfoVO.getUnitId(),roomInfoVO.getRoomNum(),roomIdArr[i],
//                            2,2,1,1,nowTime,openPwd);
//                    urPO.setUpdateTime(nowTime);
//                    iPropertyAppUserRoomDao.saveBuild(SqlUtil.durableData(urPO, PlatformConstants.TABLE_SAVE));
//                    aurCount++;
//                    isMoveIn = true;
//                }
//                //保存住户入住历史
//                if(isMoveIn ||((roomPortInfo!=null)&&("3".equals(roomPortInfo.getUserRoomStatus())))){
//                    AppUserStayInHistoryPO appUserStayInHistoryPO = new AppUserStayInHistoryPO(saveDTO.getUserId(),
//                            saveDTO.getProjectId(), roomInfoVO.getBuildId(), roomInfoVO.getUnitId(), roomInfoVO.getRoomId(),
//                            roomInfoVO.getRoomNum(),UserRoomStatusTypeEnum.HOUSE_MOVE_IN.getType());
//                    appUserStayInHistoryPOS.add(appUserStayInHistoryPO);
//                }
            }*/
            if(aurCount == roomIdArr.length){
                //添加用户授权关系的信息
                Integer arCount = 0;
                //只是改房间权限，app不传用户备注，需要获取旧值
                if(StringUtils.isEmpty(saveDTO.getUserRemarks())){
                    saveDTO.setUserRemarks(iAppMineDao.getUserRemark(saveDTO.getProjectId(),saveDTO.getUserId(),saveDTO.getLoginUserId()));
                }
                List<AppAuthRelationsSimpleInfoVO> authInfoList = iAppMineDao.getAuthRelationsRoomIds(saveDTO.getUserId(),saveDTO.getProjectId(),saveDTO.getLoginUserId());
                Date oldCreateTime = null; //原来的时间
                List<String> authRoomIdList = new ArrayList<>();
                //改变用户授权关系信息
                if((saveDTO.getAppUserInfoPO()==null)&&(authInfoList!=null))  //老用户且有授权记录
                {
                    List<AppAuthRelationsSimpleInfoVO> tempList = new ArrayList<>();
                    for(AppAuthRelationsSimpleInfoVO authInfo:authInfoList){
                        if(oldCreateTime==null){
                            oldCreateTime = DateUtil.fomatLongDate(authInfo.getCreateTime());
                        }
                        if(!newRoomIdList.contains(authInfo.getRoomId())){
                            iAppMineDao.deleteAuthRelations(saveDTO.getProjectId(),saveDTO.getUserId(),saveDTO.getLoginUserId(),authInfo.getRoomId());
                            tempList.add(authInfo);//移除不在新添加列表的记录
                        }
                        authRoomIdList.add(authInfo.getRoomId());
                    }
                    authInfoList.removeAll(tempList);
                }
                for ( AppMineRoomInfoVO roomInfo:roomInfoVOList){
                    if(oldCreateTime==null){
                        oldCreateTime = new Date();
                    }
                    if((authInfoList!=null)&&(authRoomIdList.contains(roomInfo.getRoomId()))){
                        iAppMineDao.updateAuthRelationInfo(saveDTO.getUserId(),saveDTO.getProjectId(),roomInfo.getRoomId(),saveDTO.getUserRemarks(),oldCreateTime);
                        arCount++;
                        continue;
                    }
                    AppAuthRelationsPO arPO = new AppAuthRelationsPO(saveDTO.getUserId(),saveDTO.getLoginUserId(),
                            saveDTO.getProjectId(), roomInfo.getBuildId(),roomInfo.getUnitId(),
                            roomInfo.getRoomId(),roomInfo.getRoomNum(),1,oldCreateTime);
                    arPO.setUserRemarks(saveDTO.getUserRemarks());
                    arPO.setUpdateTime(new Date());
                    arCount +=iPropertyAppAuthRelationsDao.save(SqlUtil.durableData(arPO, PlatformConstants.TABLE_SAVE));
                }
                if(arCount>0){
                    success =true;
                }else {
                    LOG.info("【APP_我的模块_添加授权人】添加授权人时保存用户授权关系失败");
                }
            }else {
                LOG.info("【APP_我的模块_添加授权人】添加授权人时保存用户房间失败");
            }
            //保存入住历史
            iPropertyHouseHoldInfoService.saveUserStayInHistory(appUserStayInHistoryPOS);
        }else{
            LOG.info("【APP_我的模块_添加授权人】添加授权人时保存用户项目失败");
        }
        //添加家人权限变更操作
        List<String> userIdList = new ArrayList<>();
        userIdList.add(saveDTO.getUserId());
        iPropertyHouseHoldInfoService.updateAppUserAuth(userIdList,saveDTO.getLoginUserId(),saveDTO.getProjectId());
      return resultMap;
    }
    /**
     * <desc>
     *      添加授权人信息。
     * <desc/>
     *
     * @param  saveDTO 请求参数
     * @return 返回授权人列表信息
     * @author shengen.T
     * @createDate 2017/11/13
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public Map<String, Object> addAuthPerson(AppMineAuthPersonExtendDTO saveDTO) throws Exception{
        String roomIdArr[] =  StringHandlerUtil.splitString(saveDTO.getRoomNums());
        Map<String, Object> resultMap = new HashMap<>(); //返回结果
        boolean success = false;
        ProjectPO projectPO = iPropertyAppUserProjectDao.getOne(saveDTO.getProjectId());
        Map<String, Object>  result=addAuthPersonTransactional(saveDTO,roomIdArr,success,projectPO);
        if((result!=null)&&(result.size()>0)){
            return result;
        }

        resultMap.put("returnCode", true);
        //用户成功迁入之后才发送指令,否则不发送，若还需物业二次审核则不发送设备指令
        if (0 == projectPO.getRecheckStatus()){
            return resultMap;
        }
        //TODO  通知云对讲设备更新指令
        if(saveDTO.getAppUserInfoPO()!=null){
            //与旺龙一卡通对接云端数据修改
            prepareUserBasisInfoForSyncToSmartCard(saveDTO.getProjectId(),SmartCardSyncDataOperTypeEnum.UPDATE,saveDTO.getAppUserInfoPO().getUserId());
        }
        //业务指令参数JSONArray
        JSONArray jsonArray = new JSONArray();
        for (int i=0;i<roomIdArr.length;i++) {
            JSONObject json = new JSONObject();
            json.put("userId", saveDTO.getUserId());
            json.put("roomId", roomIdArr[i]);
            jsonArray.add(json);
        }
        if(!jsonArray.isEmpty()){
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                    new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_USER_ROOM, jsonArray.toJSONString(), saveDTO.getProjectId());
            List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
            changeLogPOS.add(deviceBusinessChangeLogPO);
            if (changeLogPOS != null && !changeLogPOS.isEmpty()) {
                JSONObject datajs = new JSONObject();
                datajs.put("data",changeLogPOS);
                messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                        JsonUtil.toJSON(datajs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                        RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
            }

            //云电梯
            DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                    = new DeviceBusinessElevatorChangeLogPO(saveDTO.getProjectId(),
                    CloudElevatorChangeBusinessEnum.PUSH_USER_ROOM,jsonArray.toJSONString());
            List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
            deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);
            JSONObject datajs1 = new JSONObject();
            datajs1.put("data",deviceElevatorChangeLogPOS);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(datajs1),
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);

            // 云门禁
            List<DeviceBusinessEntranceChangeLogPO> changeEntranceLogPOS = new ArrayList<>();
            changeEntranceLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_USER_ROOM, jsonArray, saveDTO.getProjectId()));
            JSONObject dataJs2 = new JSONObject();
            dataJs2.put("data", changeEntranceLogPOS);
            //发送云门禁指令
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JSON.toJSONString(dataJs2),
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
            );
        }
        return resultMap;
    }

     /**
      * <desc>
      *      删除被授权人_需要事物回滚。
      * <desc/>
      *
      * @param  * @param null
      * @return
      * @author shengen.T
      * @createDate 2018-02-25
      */
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public boolean deleteAuthPersonTransactional(AppUserInfoPO userInfo,String projectId,String parentUserId, List<AppMineRoomInfoVO> roomIdList) throws Exception{
            Integer delCount =0;
            Integer deluserRoomCount = 0;
            boolean isSuccess = false;
            List<AppUserStayInHistoryPO> appUserStayInHistoryPOS = new ArrayList<>();
            if ((roomIdList != null) && (roomIdList.size() > 0)) {
                delCount = iAppMineDao.deleteAuthRelations(projectId, userInfo.getUserId(), parentUserId, "");
                if (delCount > 0) {
                    Map<String, Object> delMoveOutParams = new HashMap<>();
                    delMoveOutParams.put("userId", userInfo.getUserId());
                    delMoveOutParams.put("projectId", projectId);
                    delMoveOutParams.put("status", UserRoomStatusTypeEnum.HOUSE_MOVE_OUT.getType());
                    //因用户房间对应数据仅维护一条，当该删除家人后，将授权人id字段置为null
                    delMoveOutParams.put("authUserId", "-1");
                    for (AppMineRoomInfoVO roomInfo : roomIdList) {
                        delMoveOutParams.put("roomId", roomInfo.getRoomId());
                        deluserRoomCount += iAppMineDao.updateUserRoomInfo(delMoveOutParams);
                        //保存住户入住历史
                        AppUserStayInHistoryPO appUserStayInHistoryPO = new AppUserStayInHistoryPO(userInfo.getUserId(),
                                projectId, roomInfo.getBuildId(), roomInfo.getUnitId(), roomInfo.getRoomId(),
                                roomInfo.getRoomNum(), UserRoomStatusTypeEnum.HOUSE_MOVE_OUT.getType());
                        appUserStayInHistoryPOS.add(appUserStayInHistoryPO);
                    }
                    //迁出历史
                    iPropertyHouseHoldInfoService.saveUserStayInHistory(appUserStayInHistoryPOS);
                    isSuccess = (deluserRoomCount == roomIdList.size()) ? true : false;
                }
            }
            Integer count = iAppMineDao.checkUserRoomCount(userInfo.getUserId(), projectId);
            if (count < 1) {
                //已授权的用户虽已不再房间，但是在用户列表中要体现
//                iAppMineDao.setUserProjectStatus(userInfo.getUserId(), projectId, 0);
            }
            //删除家人权限变更操作
            List<String> userIdList = new ArrayList<>();
            userIdList.add(userInfo.getUserId());
            iPropertyHouseHoldInfoService.updateAppUserAuth(userIdList, parentUserId, projectId);
           // AppUserInfoPO appUserInfoPO = new AppUserInfoPO();
          //  appUserInfoPO.setPhoneNum(authPhoneNo);
          return isSuccess;
    }
    /**
     * <desc>
     *      删除被授权的人。
     * <desc/>
     *
     * @param  parentUserId 业主的用户ID
     * @param  authPhoneNo 被授权的手机号
     * @param  projectId 项目编号
     * @return 返回影响行数
     * @author shengen.T
     * @createDate 2017/11/15
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public boolean deleteAuthPerson(String parentUserId,String authPhoneNo,String projectId) throws Exception{

        AppUserInfoPO userInfo = iAppMineDao.getUserInfoByPhoneNo(authPhoneNo);
        boolean isSuccess = false;
        if((userInfo!=null)&&StringUtils.isNotEmpty(userInfo.getUserId())) {
            List<AppMineRoomInfoVO> roomIdList = iAppMineDao.getAuthRelationsRoomInfos(projectId, userInfo.getUserId(), parentUserId);
            isSuccess=deleteAuthPersonTransactional(userInfo, projectId,parentUserId,roomIdList);
            //TODO  通知云对讲设备更新指令
            //业务指令参数JSONArray
            JSONArray jsonArray = new JSONArray();
            for (AppMineRoomInfoVO roomInfo : roomIdList) {
                JSONObject json = new JSONObject();
                json.put("userId", userInfo.getUserId());
                json.put("roomId", roomInfo.getRoomId());
                jsonArray.add(json);
            }
            if (!jsonArray.isEmpty()) {
                DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                        new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_USER_ROOM, jsonArray.toJSONString(), projectId);
                List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
                changeLogPOS.add(deviceBusinessChangeLogPO);
                if (changeLogPOS != null && !changeLogPOS.isEmpty()) {
                    JSONObject datajs = new JSONObject();
                    datajs.put("data", changeLogPOS);
                    messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                            JSON.toJSONString(datajs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                            RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
                }

                //云电梯
                DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                        = new DeviceBusinessElevatorChangeLogPO(projectId,
                        CloudElevatorChangeBusinessEnum.PUSH_USER_ROOM,jsonArray.toJSONString());
                List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
                deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);
                JSONObject datajs1 = new JSONObject();
                datajs1.put("data",deviceElevatorChangeLogPOS);
                messageSender.send(
                        RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                        JsonUtil.toJSON(datajs1),
                        RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                        RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);

                // 云门禁
                List<DeviceBusinessEntranceChangeLogPO> changeEntranceLogPOS = new ArrayList<>();
                changeEntranceLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_USER_ROOM, jsonArray, projectId));
                JSONObject dataJs2 = new JSONObject();
                dataJs2.put("data", changeEntranceLogPOS);
                //发送云门禁指令
                messageSender.send(
                        RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                        JSON.toJSONString(dataJs2),
                        RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                        RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
                );
            }
        }
        return isSuccess;
    }

    /**
     * <desc>
     *      获取用户二维码
     * </desc>
     *
     * @param projectId 项目id
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/15
     */
    @Override
    public AppGetQrcodeVO getUserQrcode(String projectId, String userId,String roomId) throws ParseException {
        AppGetQrcodeVO vo;
        try {
            vo = iAppMineDao.getUserQrcode(projectId, userId);
        }catch (Exception e){
            LOG.error(String.format("用户id为：%s的用户与项目id:%s 项目关联关系异常",userId,projectId));
            vo=null;
        }
        //获取项目二维码配置信息
        PropertyQrcodeValidVO valid = iAppMineDao.getPropertyQrocdeVliadInfo(roomId);
        vo.setQrcodeMode("0");
        if(valid != null && valid.getProjectChargeMode() != null  && valid.getProjectChargeMode().equals(2)){
            if(valid.getRoomChargeMode()!=null && valid.getRoomChargeMode() == 1){
                //按次
                if(valid.getUsableCount() != null && valid.getUsableCount() <= 0){
                    vo.setQrcodeMode("1");
                }
                if(valid.getUsableCount() != null){
                    vo.setMsg(valid.getUsableCount().toString());
                }
            }else if(valid.getRoomChargeMode()!=null && valid.getRoomChargeMode() == 2){
                //按有效期
                Date now = DateUtil.formatStringToDate(DateUtil.fomatDate(new Date(), DateUtil.YMDSQL), DateUtil.YMDSQL);
                if(StringUtils.isNotBlank(valid.getEndTime())){
                    Date roomDate = DateUtil.formatStringToDate(valid.getEndTime(),DateUtil.YMDSQL);
                    if(roomDate.getTime() < now.getTime()){
                        vo.setQrcodeMode("2");
                    }
                    vo.setMsg(valid.getEndTime());
                }
            }
        }
        vo.setEndTimeHint("120");
        if(vo!=null && vo.getEndTime() != null) {
            vo.setEndTime(DateUtil.formatStringToDate(vo.getEndTime(), DateUtil.DATE_FORMAT_TYPE1).getTime() + "");
        }else if(vo==null){
            vo=(AppGetQrcodeVO)StringHandlerUtil.formatString(new AppGetQrcodeVO());
        }
        if(StringUtils.isBlank(vo.getMsg())){
            vo.setMsg("");
        }
        return vo;
    }


    /**
     * <desc>
     *      更新授权人的备注。
     * <desc/>
     *
     * @param authPhoneNo 授权手机号
     * @param projectId 项目编号
     * @param parentUserId 业主ID
     * @return
     * @author shengen.T
     * @createDate 2017/11/15
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer updateUserRemarks(String authPhoneNo,String projectId,String parentUserId,String userRemarks) throws Exception{
        //LOG.info(String.format("【APP_我的模块_更新授权人的备注】手机号:%s—项目编号：%s—业主Id:%s—用户备注：%s",authPhoneNo,projectId,parentUserId,userRemarks));
        AppUserInfoPO userInfo= iAppMineDao.getUserInfoByPhoneNo(authPhoneNo);
        Integer count =0;
        if((userInfo!=null)&&StringUtils.isNotEmpty(userInfo.getUserId())){
            count =iAppMineDao.updateUserRemark(projectId,userInfo.getUserId(),parentUserId,userRemarks);
            //LOG.info("执行成功！");
        }
        return count;
    }

     /**
      * <desc>
      *      与旺龙一卡通对接云端数据修改。
      * <desc/>
      *
      * @param  projectId 项目编号
      * @param  dataOperType 操作方式  1-更新| 2-删除| 3-增加
      * @param userId 用户信息数据
      * @return
      * @author shengen.T
      * @createDate 2017/11/27
      */
    public void prepareUserBasisInfoForSyncToSmartCard(String projectId, SmartCardSyncDataOperTypeEnum dataOperType,
                                                       String userId) throws Exception{
        //有数据变动的用户信息集
        //推送数据给一卡通
        List<SmartCardSyncDataPullUserBasisInfoDTO> basisInfoDTOS = new ArrayList();

        List<SmartCardSyncDataPullUserBasisInfoDTO> basisInfoDTOList = iSmartCardUserInfoDao.getUserBasisInfo(projectId,userId);
        if ((null != basisInfoDTOList) && (!basisInfoDTOList.isEmpty())){
            basisInfoDTOS.add(basisInfoDTOList.get(0));
        } else {
            LOG.info(String.format("未能查询到用户：%s 在项目：%s中的信息",userId,projectId));
        }

        if (basisInfoDTOS.isEmpty()){
            return;
        }
        //有数据变动的用户信息集
        String data = JSON.toJSONString(basisInfoDTOS);
        //打包
          SmartCardSyncDataPullDTO smartCardSyncDataPullDTO = new SmartCardSyncDataPullDTO(projectId, data, dataOperType,
                  SmartCardSyncDataTypeEnum.USER_BASIS_DATA);
        //发送
        JSONObject dataJs = new JSONObject();
        dataJs.put("data",JSONObject.toJSON(smartCardSyncDataPullDTO));
         messageSender.send(RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_MODIFY_QUEUE,JsonUtil.toJSON(dataJs),
                 RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_EXCHANGE, RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_MODIFY_ROUTING_KEY);
    }

    /**
     * <desc>
     *      更新家人的开门密码。
     * <desc/>
     *
     * @param userId 业主用户ID
     * @param projectId 项目编号
     * @param openPwd 开门密码
     * @return
     * @author shengen.T
     * @createDate 2017-12-07
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public boolean updateUserRoomOpenPwd(String userId,String projectId,String openPwd) throws Exception{
        Map<String,Object> params = new HashMap<>();
        params.put("currentPage",0);
        params.put("pageSize",999);
        params.put("projectId",projectId);
        params.put("loginUserId",userId);
        List<AppMineGetAuthPersonPageVO> pageVOS = iAppMineDao.getAuthPersonPage(params);
        if((pageVOS!=null)&&(pageVOS.size()>0)){
            for (AppMineGetAuthPersonPageVO PageVO:pageVOS){
                List<AppMineGetAddressInfoVO> addressInfoVOS = iAppMineDao.getAddressInfo(userId,PageVO.getUserId(),projectId);
               for (AppMineGetAddressInfoVO vo:addressInfoVOS){
                   iAppMineDao.updateUserRoomOpenPwd(PageVO.getUserId(),projectId,vo.getRoomNum(),openPwd);
               }
            }
            return true;
        }
        return false;
    }

    /**
     * <desc>
     *      获取房间的入住人数
     * <desc/>
     *
     * @param  userId 用户ID
     * @param  projectId  项目编号
     * @param  roomId 房间编号
     * @return
     * @author shengen.T
     * @createDate 2018-01-10
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public Integer getUserRoomCount(String userId,String projectId,String roomId) throws Exception{
         return iAppMineDao.getUserRoomCount(userId,projectId,roomId);
    }

    /**
     * <desc>
     *      根据手机号查询用户ID
     * <desc/>
     *
     * @param  phoneNo 授权人手机号
     * @return
     * @author shengen.T
     * @createDate 2018-01-10
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public AppUserInfoPO getUserInfoByPhoneNo(String phoneNo) throws Exception{
        return iAppMineDao.getUserInfoByPhoneNo(phoneNo);
    }


    /**
     * <desc>
     *     跟据项目编号获取最大授权数。
     * <desc/>
     *
     * @param  projectId 项目编号
     * @return
     * @author shengen.T
     * @createDate 2018-01-10
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public Integer getMaxAuthNum(String projectId) throws Exception{
        return iAppMineDao.getMaxAuthNum(projectId);
    }

    /**
     * <desc>
     *      获取房间名称。
     * <desc/>
     *
     * @param roomId 房间编号
     * @param projectId 项目编号
     * @return
     * @author shengen.T
     * @createDate 2017-12-14
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public String getRoomName(String projectId, String roomId) throws Exception{
        return iAppMineDao.getRoomName(projectId,roomId);
    }

    /**
     * <desc>
     *      获取用户在该项目该业主下是否授权过房间的数目。
     * <desc/>
     *
     * @param  parentUserId 业主ID
     * @param  userId 用户ID
     * @param  projectId 项目ID
     * @return
     * @author shengen.T
     * @createDate 2017/11/23
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public Integer getUserAuthRelationCount(String parentUserId,String userId,String projectId) throws Exception{
        return iAppMineDao.getUserAuthRelationCount(parentUserId,userId,projectId);
    }


    /**
     * <desc>
     *      获取APP用户项目关系表的状态。
     * <desc/>
     *
     * @param  userId
     * @param  projectId
     * @return
     * @author shengen.T
     * @createDate 2018-01-16
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
     public Integer getAppUserProjectStatus(String userId,String projectId) throws Exception{
         return iAppMineDao.getUserProjectStatus(userId,projectId);
     }

     /**
      * <desc>
      *     用户是否是vip
      * <desc/>
      *
      * @param  userId
      * @param  projectId
      * @return
      * @author pengwei
      * @createDate 2020-11-12
      */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
     public boolean appUserIsVip(String userId,String projectId) throws Exception{
        //用户标签，1-VIP，2-障碍人士，多个英文逗号连接
        String  userLabel  = iAppMineDao.getUserLabel(userId,projectId);
        if(StringUtils.isNotEmpty(userLabel)){
            String[]  labelList =  userLabel.split(",");
            for(String  label:labelList){
                //1是vip
                if("1".equals(label)){
                    return  true;
                }
            }
        }
         return false;
     }

    /**
     * <desc>
     *      获取项目状态。
     * <desc/>
     *
     * @param  projectId
     * @return
     * @author Qiang.S
     * @createDate 2018-01-07
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public String getProjectStatus(String projectId) throws Exception{
        return iAppMineDao.getProjectStatus(projectId);
    }


    /**
     * <desc>
     *      获取业主拥有权限的房间列表ID。
     * <desc/>
     *
     * @param userId 用户ID
     * @param projectId 项目ID
     * @return
     * @author shengen.T
     * @createDate 2018-02-02
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public List<String> getOwnerRoomInfoLists(String userId, String projectId) throws Exception{
         return  iAppMineDao.getOwnerRoomInfoLists(userId,projectId);
    }


    /**
     * <desc>
     *      获取审核通过的房间列表。
     * <desc/>
     *
     * @param  projectId
     * @param  userId
     * @param  pageNum
     * @return
     * @author shengen.T
     * @createDate 2018-03-26
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public Page<AppPassRoomListVO> getPassRoomList(String projectId, String userId, String pageNum) throws Exception{
        //将DTO转换为Map params
        Map<String, Object> params = new HashMap<>();
        //分页类默认pageSize为20
        Page<AppPassRoomListVO> page = new Page<>();
        page.getPage().setPageSize("15");
        page.getPage().setCurrentPage(pageNum);
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        params.put("projectId",projectId);
        params.put("userId",userId);
        List<AppPassRoomListVO> pageVOS = iAppMineDao.getPassRoomPage(params);
        //填充返回数据集
        page.setRows(pageVOS,iAppMineDao.getPassRoomPageCount(params));
        return page;
    }

    /**
     * <desc>
     * 保存app端监听linPhone状态的数据
     * <desc/>
     *
     * @param message linPhone状态的数据
     * @return
     * @author Juguang.S
     * @createDate 2018/05/08
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public void saveMessage(String message,String phoneNum) throws Exception{

        AppTempSaveMessagePO messagePO = new AppTempSaveMessagePO();
        messagePO.setCreateTime(new Date());
        messagePO.setMessage(message);
        messagePO.setPhoneNum(phoneNum);
        iAppMineDao.save(SqlUtil.durableData(messagePO, PlatformConstants.TABLE_SAVE));
    }

    /**
     * <desc>
     *  根据时间或手机号查询linPhone状态的数据
     * <desc/>
     *
     * @param findTime 传入查询时间
     * @param phoneNum 传入查询手机号
     * @return
     * @author Juguang.S
     * @createDate 2018/05/08
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public List<AppTempSaveMessagePO> findMessageBytime(String findTime,String phoneNum) throws Exception{

        return iAppMineDao.findMessageBytime(findTime,phoneNum);
    }

    /**
     * <desc>
     *      获取用户人脸创建信息
     * </desc>
     *
     * @param userId 用户id
     * @param projectId 项目id
     * @return
     * @author Qiang.S
     * @createDate 2018/05/08
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public AppUserFaceVO getCreateBaiduFaceInfo(String userId, String projectId) throws Exception{
        return  iAppMineDao.getCreateBaiduFaceInfo(userId,projectId);
    }

    /**
     * <desc>
     *      修改用户手机
     * </desc>
     *
     * @param userId 用户id
     * @param newPhoneNo 新手机号
     * @return
     * @author Qiang.S
     * @createDate 2018/07/03
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public Integer updateUserPhone(String userId, String newPhoneNo) throws Exception{
        return  iAppMineDao.updateUserPhone(userId,newPhoneNo);
    }

    /**
     * <desc>
     *      因集成灵云快智需要，需将旧数据用户的SIP账号改为灵云快智的userId，前端移动端无需调此接口
     *      还需将用户信息推送给所有的云对讲设备
     * <desc/>
     *
     * @return
     * @author Juguang.S
     * @createDate 2018-08-24
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void updateSipAccount() throws Exception {
        List<Map<String,String>> appUserInfo = iAppMineDao.getAppUserInfo();
        int number = 0;
        for(Map<String,String> mapParams : appUserInfo){
            String userId = mapParams.get("userId");
            String phoneNum = mapParams.get("phoneNum");
            String projectId = mapParams.get("projectId");
            String sipAccount = mapParams.get("sipAccount");
            String sipPsd = Md5EncryptUtil.md5(userId + phoneNum).toLowerCase();
            //针对开启云对讲并且通过审核的userId查询是否已创建灵云快智的账号，如有则跳过
            Integer count = iAppLykzCloudIntercomAccountService.getUserInfoByUserId(userId);
            //String regex = "^((1[3,5,8][0-9])|(14[5,7])|(17[0,6,7,8])|(19[7]))\\d{8}$";
            String regex = "^1[3|4|5|6|7|8|9]\\d{9}$";
            Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
            Matcher m = p.matcher(phoneNum);
            if(!m.matches()){
                continue;
            }

            Map<String,String> resultMap = iAppLykzCloudIntercomAccountService.getLykzCloudIntercomAccountByMoblie(phoneNum,"");

            if(resultMap==null){
                CloudIntercomAccountInfoPO infoPO = iAppLykzCloudIntercomAccountService.createLykzCloudIntercomAccount(userId,phoneNum,"","");
                //并将灵云快智的uerId做为sip账号保存至app-user-project表中
                if(infoPO!=null){

                    //删除原SIP相关信息,并添加/更新SIP信息
                    PropertySubscriberHanlerDTO subscriberHanlerDTO = new PropertySubscriberHanlerDTO(projectId,infoPO.getClientUserId(), sipPsd, sipAccount);
                    JSONObject js = new JSONObject();
                    js.put("data",JSONObject.toJSON(subscriberHanlerDTO));
                    messageSender.send(RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_QUEUE, JsonUtil.toJSON(js), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                            RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_KEY);

                    iAppLykzCloudIntercomAccountService.updateUserSipAccount(infoPO.getClientUserId(),userId,sipPsd);
                }
            }else{
                //如果该用户已经绑定灵云账号 ，则从灵云获取绑定信息并进行保存处理
                //首先根据手机号查询cloud_intercom_account_info表中是否已有该用户灵云信息数据 没有则保存
                if(iAppLykzCloudIntercomAccountService.getExistLykzInfo(resultMap.get("lykzUserId"))==0){
                    CloudIntercomAccountInfoPO  infoPO = new CloudIntercomAccountInfoPO();
                    String lykzId = LogicIdUtil.bussinessId();
                    infoPO.setCloudIntercomAccountId(lykzId);
                    infoPO.setAccountType(1);
                    infoPO.setAccount(resultMap.get("clientNumber"));
                    infoPO.setToken(resultMap.get("loginToken"));
                    infoPO.setClientPwd(resultMap.get("clientPwd"));
                    infoPO.setClientUserId(resultMap.get("lykzUserId"));
                    infoPO.setStatus(1);
                    infoPO.setCreateTime(new Date());
                    Integer result = iAppUserLykzAccountDao.save(SqlUtil.durableData(infoPO, PlatformConstants.TABLE_SAVE));
                    if(result>0){
                        iAppUserLykzAccountDao.updateAppUserInfo(userId,lykzId);
                    }

                    //删除原SIP相关信息,并添加/更新SIP信息
                    PropertySubscriberHanlerDTO subscriberHanlerDTO = new PropertySubscriberHanlerDTO(projectId,infoPO.getClientUserId(), sipPsd, sipAccount);
                    JSONObject js = new JSONObject();
                    js.put("data",JSONObject.toJSON(subscriberHanlerDTO));
                    messageSender.send(RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_QUEUE, JsonUtil.toJSON(js), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                            RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_KEY);
                }
                iAppLykzCloudIntercomAccountService.updateUserSipAccount(resultMap.get("lykzUserId"),userId,sipPsd);
            }
            number++;
            //LOG.info("已处理账号数量："+number);
        }

    }

    /**
     * <desc>
     *      推送开启云对讲服务的项目设备重启指令
     * <desc/>
     *
     * @return
     * @author Juguang.S
     * @createDate 2019-01-03
     */
    public void pushCommand() throws Exception {
        //推送云对讲指令 向所有的设备推房间全量更新
        List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS  = new ArrayList<>();
        List<String> projectList = iAppUserLykzAccountDao.getProjectidPushCommand();
        for(String projectId : projectList){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("projectId",projectId);
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO
                    = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_RELOGIN,jsonObject,projectId);
            deviceBusinessChangeLogPOS.add(deviceBusinessChangeLogPO);
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("data",deviceBusinessChangeLogPOS);

        //云对讲业务指令
        messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                JsonUtil.toJSON(jsonObject), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
    }

    /**
     * <desc>
     *      因集成灵云快智测试需要，根据userId释放灵云快智账号，前端移动端无需调此接口
     * <desc/>
     *
     * @return
     * @author Juguang.S
     * @createDate 2018-09-11
     */
    @Override
    public void dropSipAccount() throws Exception {
        iAppLykzCloudIntercomAccountService.dropSipAccount();
    }

    /**
     * <desc>
     *      补救批量给旧数据绑定灵云快智账号时遗漏账号的操作
     * <desc/>
     *
     * @param  phoneNum 手机号 如有值则创建此手机号的灵云快智账号，如无值则处理所有遗漏创建灵云快智的情况
     * @return
     * @author Juguang.S
     * @createDate 2018-10-15
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public void remedySipAccount(String phoneNum) throws Exception {
        //手机号 如有值则创建此手机号的灵云快智账号，如无值则处理所有遗漏创建灵云快智的情况
        List<Map<String,String>> appUserInfo;
        if(phoneNum.equals("")){
            appUserInfo = iAppMineDao.remedySipAccount();
        }else{
            appUserInfo = iAppMineDao.remedySipAccountByPhoneNum(phoneNum);
        }

        JSONObject datajs = new JSONObject();
        datajs.put("data",appUserInfo);

        messageSender.send(RabbitMQConstant.RABBITMQ_CREATE_LYKZ_CLOUD_INTERCOM_ACCOUNT_QUEUE, JSON.toJSONString(datajs),
                RabbitMQConstant.RABBITMQ_USER_EXCHANGE, RabbitMQConstant.RABBITMQ_CREATE_LYKZ_CLOUD_INTERCOM_ACCOUNT_KEY);
    }

    /**
     * <desc>
     *      由账单id查询项目微信公众号appId
     * <desc/>
     *
     * @return 项目微信公众号appId
     * @author wangzhi
     * @createDate 2019/10/23
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Map<String, Object> getAppIdByBillId(String billId) throws Exception {
        return iAppMineDao.getAppIdByBillId(billId);
    }

    /**
     * <desc>
     *      sdk删除用户信息
     * <desc/>
     *
     * @param userId 用户id
     * @return
     * @author Qiang.S
     * @createDate 2020/07/02
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void logOffUserForSDK(String userId) throws Exception {
        List<String> projectIds = iOperateUserManageDao.getUserPorject(userId);
        AppUserInfoPO appUserInfoPO = iAppMineDao.getUserInfoByUserId(userId);
        AppLogoffUserHistoryPO logoff = new AppLogoffUserHistoryPO();
        logoff.setUserId(appUserInfoPO.getUserId());
        logoff.setPhone(appUserInfoPO.getPhoneNum());
        logoff.setLogoffTime(new Date());
        logoff.setRealName(appUserInfoPO.getRealName());
        logoff.setCreateTime(logoff.getLogoffTime());
        logoff.setUpdateTime(logoff.getLogoffTime());
        logoff.setLogoffUserId(LogicIdUtil.bussinessId());
        logoff.setStatus(DataStatusEnum.NORMAL.getType());
        //处理项目数据app_user_project
        iAppMineDao.setLogOffUserProjectByUserId(userId);
        //处理房间数据app_user_room
        iAppMineDao.setLogOffUserRoomByUserId(userId);
        //处理设备权限数据
        iAppMineDao.setLogOffUserElevatorByUserId(userId);
        iAppMineDao.setLogOffUserEntranceByUserId(userId);
        iAppMineDao.setLogOffUserCloudIntercomByUserId(userId);
        iAppMineDao.logOffForSDK(userId);
        iAppMineDao.save(SqlUtil.durableData(logoff,PlatformConstants.TABLE_SAVE));

        //重新发送2号指令
        for (String projectId : projectIds) {
            List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
            JSONObject json = new JSONObject();
            json.put("userId", userId);
            json.put("projectId", projectId);
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                    new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_USER_PROJECT, json, projectId);
            changeLogPOS.add(deviceBusinessChangeLogPO);
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", changeLogPOS);
            //云对讲
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);

            //云电梯
            DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                    = new DeviceBusinessElevatorChangeLogPO(projectId,
                    CloudElevatorChangeBusinessEnum.PUSH_USER_PROJECT, json.toJSONString());
            List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
            deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);
            dataJs.put("data", deviceElevatorChangeLogPOS);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(dataJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);

            // 云门禁
            List<DeviceBusinessEntranceChangeLogPO> changeEntranceLogPOS = new ArrayList<>();
            changeEntranceLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_USER_PROJECT, json, projectId));
            dataJs.put("data", changeEntranceLogPOS);
            //发送云门禁指令
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JSON.toJSONString(dataJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
            );
        }
    }

    /**
     * <desc>
     *      物业注销该项目下的人脸信息
     * <desc/>
     *
     * @param userId 用户id
     * @param projectId 项目id
     * @return
     * @author Juguang.S
     * @createDate 2021/04/20
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void logOffUserForProperty(String userId,String projectId) throws Exception {
        //处理项目数据app_user_project
        iAppMineDao.deleteFaceInfoByUserId(userId,projectId);

        //重新发送2号指令
        List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
        JSONObject json = new JSONObject();
        json.put("userId", userId);
        json.put("projectId", projectId);
        DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_USER_PROJECT, json, projectId);
        changeLogPOS.add(deviceBusinessChangeLogPO);
        JSONObject dataJs = new JSONObject();
        dataJs.put("data", changeLogPOS);
        //云对讲
        messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);

        //云电梯
        DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                = new DeviceBusinessElevatorChangeLogPO(projectId,
                CloudElevatorChangeBusinessEnum.PUSH_USER_PROJECT, json.toJSONString());
        List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
        deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);
        dataJs.put("data", deviceElevatorChangeLogPOS);
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                JsonUtil.toJSON(dataJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);

        // 云门禁
        List<DeviceBusinessEntranceChangeLogPO> changeEntranceLogPOS = new ArrayList<>();
        changeEntranceLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_USER_PROJECT, json, projectId));
        dataJs.put("data", changeEntranceLogPOS);
        //发送云门禁指令
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                JSON.toJSONString(dataJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
        );
    }

    /**
     * <desc>
     *      获取历史反馈列表
     * </desc>
     *
     * @param userId 用户id列表
     * @param projectId 项目id
     * @param page 页码
     * @return
     * @Author Zhu.yj
     * @createDate  2020/11/12
     */
    @Override
    public List<AppFeedbackInfoVO> getFeedbackList(String userId, String projectId, String page) throws Exception {

        Page pageParam = new Page();
        pageParam.getPage().setPageSize("15");
        pageParam.getPage().setCurrentPage(page);
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        params.put("projectId", projectId);
        params.put("startSlip", pageParam.getPage().getStartSlip());
        params.put("pageSize", pageParam.getPage().getPageSize());
        return iAppMineDao.getFeedbackList(params);
    }

    /**
     * <desc>
     *      获取历史反馈列表
     * </desc>
     *
     * @param feedbackId 用户id列表
     * @return 反馈详情
     * @Author Zhu.yj
     * @createDate  2020/11/12
     */
    @Override
    public AppFeedbackInfoVO getFeedbackDetail(String feedbackId) throws Exception {
        DateFormat dateFormat = new SimpleDateFormat(DateUtil.YYYYMMDDHHMM);
        FeedbackInfoPO feedbackInfoPO = iAppMineDao.getFeedbackDetail(feedbackId);
        if (feedbackInfoPO != null){
            AppFeedbackInfoVO appFeedbackInfoVO = new AppFeedbackInfoVO();
            appFeedbackInfoVO.setFeedId(feedbackInfoPO.getFeedbackId());
            appFeedbackInfoVO.setHeadline(feedbackInfoPO.getProblemTypeString());
            appFeedbackInfoVO.setContent(feedbackInfoPO.getFeedbackInfo());
            appFeedbackInfoVO.setImageUrl(feedbackInfoPO.getImageUrl());
            appFeedbackInfoVO.setCreateTime(dateFormat.format(feedbackInfoPO.getCreateTime()));
            appFeedbackInfoVO.setStateArr(this.getReplyContentList(feedbackInfoPO));
            appFeedbackInfoVO.setPhoneModel(feedbackInfoPO.getPhoneModel());
            appFeedbackInfoVO.setAppVersion(feedbackInfoPO.getAppVersion());
            appFeedbackInfoVO.setSystemName(feedbackInfoPO.getOperateSystem());
            appFeedbackInfoVO.setNetType(feedbackInfoPO.getNetType());
            return appFeedbackInfoVO;
        }
        return null;
    }

    /**
     * <desc>
     *      组装反馈处理信息列表
     * </desc>
     *
     * @param feedbackInfoPO 反馈信息详细字段
     * @return
     * @Author Zhu.yj
     * @createDate  2020/11/13
     */
    private List<Map<String, Object>> getReplyContentList(FeedbackInfoPO feedbackInfoPO) throws Exception{
        Date nowTime = new Date();
        DateFormat dateFormat = new SimpleDateFormat(DateUtil.YYYYMMDDHHMM);
        List<Map<String, Object>> contentList = new ArrayList<>();
        Map<String, Object> resultMap = new HashMap<>();
        //系统回复时间
        String replyTime = dateFormat.format(DateUtil.addCurrentTime(feedbackInfoPO.getCreateTime(), 60 * 1000));
        //反馈创建时间
        String createTime = dateFormat.format(feedbackInfoPO.getCreateTime());
        //尚没有人回复h或不展示回复消息
        if (StringUtils.isBlank(feedbackInfoPO.getReplyContent())){
            //当前时间在反馈创建1分钟后，发送消息
            if (DateUtil.reduceCurrentTime(nowTime, 60 * 1000).after(feedbackInfoPO.getCreateTime())){
                resultMap.put("state", 1);
                resultMap.put("title", REPLY_CONTENT);
                resultMap.put("time", replyTime);
                contentList.add(resultMap);
                resultMap = new HashMap<>();
                resultMap.put("state", 0);
                resultMap.put("title", COMMIT_FEEDBACK);
                resultMap.put("time", createTime);
                contentList.add(resultMap);
            }else {
                resultMap.put("state", 1);
                resultMap.put("title", COMMIT_FEEDBACK);
                resultMap.put("time", createTime);
                contentList.add(resultMap);
            }
        //反馈已有人回复
        }else {
            if (DateUtil.reduceCurrentTime(feedbackInfoPO.getUpdateTime(), 60 * 1000).after(feedbackInfoPO.getCreateTime())){
                resultMap.put("state", 1);
                resultMap.put("title", feedbackInfoPO.getReplyContent());
                resultMap.put("time", dateFormat.format(feedbackInfoPO.getUpdateTime()));
                contentList.add(resultMap);
                resultMap = new HashMap<>();
                resultMap.put("state", 0);
                resultMap.put("title", REPLY_CONTENT);
                resultMap.put("time", replyTime);
                contentList.add(resultMap);
                resultMap = new HashMap<>();
                resultMap.put("state", 0);
                resultMap.put("title", COMMIT_FEEDBACK);
                resultMap.put("time", createTime);
                contentList.add(resultMap);
            }
            else {
                resultMap.put("state", 1);
                resultMap.put("title", feedbackInfoPO.getReplyContent());
                resultMap.put("time", dateFormat.format(feedbackInfoPO.getUpdateTime()));
                contentList.add(resultMap);
                resultMap = new HashMap<>();
                resultMap.put("state", 0);
                resultMap.put("title", COMMIT_FEEDBACK);
                resultMap.put("time", createTime);
                contentList.add(resultMap);
            }
        }
        return contentList;
    }
    /**
     * <desc>
     *      京东非标-注销用户
     * </desc>
     *
     * @param userId
     * @Author Zhu.yj
     * @createDate  2020/12/17
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void logOffUserForJdSdk(String userId, String projectId) throws Exception{
        if(StringUtils.isBlank(projectId)){
            return;
        }
        iAppMineDao.setLogOffUserProject(userId, projectId);
        iAppMineDao.setLogOffUserElevator(userId, projectId);

        List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
        JSONObject json = new JSONObject();
        json.put("userId", userId);
        json.put("projectId", projectId);
        JSONObject dataJs = new JSONObject();
        //云电梯
        DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                = new DeviceBusinessElevatorChangeLogPO(projectId,
                CloudElevatorChangeBusinessEnum.PUSH_USER_PROJECT, json.toJSONString());
        List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
        deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);
        dataJs.put("data", deviceElevatorChangeLogPOS);
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                JsonUtil.toJSON(dataJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
    }

}
